/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import dominio.Estudiante;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.persistence.*;
import javax.swing.JOptionPane;

/**
 *
 * @author eagle
 */
public class EstudianteDao {

    private EntityManager em;

    public EstudianteDao(EntityManager em) {
        this.em = em;
    }

    /**
     * La funcion crea un estudiante con los datos que se piden en la interfaz
     * de inscripcion y los demas los deja nulos o con valores por defecto (-1) y se
     * solicitaran en formalizacion de matricula. todos los atributos de tipo
     * String se cambian a minusculas antes de almacenarsen en la base de datos
     *
     * El id en la base de datos sia, debe ser autonumerico para que pueda asignarse
     * un id autoincremental a cada nuevo estudiante.
     *
     * se asignara 1 en el campo preinscrito a los estudiantes mediante esta funcion
     *
     *
     *
     * @param nombres
     * @param apellidos
     * @param idgrado
     * @param telefono
     * @param docidentidad
     * @param genero
     * @param edad
     * @param direcion
     * @return
     */
    public Estudiante crearEstudianteEnPreinscripcion(String nombres,
            String apellidos,
            String idcurso,
            int idgrado, //el id lo enviara la clase control correspondiente
            int telefono,
            long docidentidad,
            String genero,
            String direcion,
            String nombremadre,
            String apellidomadre,
            long documentomadre,
            String nombrepadre,
            String apellidopadre,
            long documentopadre,
            String fechanacimiento,
            String edadest) {



        Estudiante estudiante = new Estudiante();
        estudiante.setNombreEst(nombres.toLowerCase());
        estudiante.setApellidoEst(apellidos.toLowerCase());
        estudiante.setTelefonoEst(telefono);
        estudiante.setDocEstudiante(docidentidad);
        estudiante.setGeneroEst(genero.toLowerCase());
        estudiante.setDireccionEst(direcion.toLowerCase());
        Date calendar = new Date();
        estudiante.setAnoIngreso(calendar.getYear());
        estudiante.setApellidoMadre(apellidomadre);
        estudiante.setApellidoPadre(apellidopadre);
        estudiante.setDocMadre(documentomadre);
        estudiante.setDocPadre(documentopadre);
        estudiante.setIdEstudiante(0L);
        estudiante.setIdEstudiante(this.retornarultimoId() + 1);
        estudiante.setPreInscrito(1);       //1 si esta inscrito, 0 si no
        estudiante.setInscrito(0);          //1 si esta inscrito, 0 si no
        estudiante.setMatriculado(0);       //1 si esta matriculado, 0 si no
        estudiante.setNombreMadre(nombremadre);
        estudiante.setNombrePadre(nombrepadre);
        estudiante.setNombreUsuario(null);
        estudiante.setPreInscrito(1);
        estudiante.setTelMadre(-1);
        estudiante.setTelPadre(-1);
        estudiante.setFechaPreinscripcion(calendar.getYear()+1900);
        estudiante.setFechaNacimientoEst(fechanacimiento);
        estudiante.setIdGrado(idgrado);       //Por ahora todos los estudiantes los manda a primero xD
        //em.persist(estudiante);
        em.persist(estudiante);
        return estudiante;

    }

    /**
     * La funcion busca un estudiante por su nombre y apellido, retornando una instancia
     * al estudiante creado
     * @param apellido
     * @param nombre
     * @return referencia de tipo Estudiante
     */
    public Estudiante encontrarEstudiantePorNombreYApellido(String apellido, String nombre) {
        String queryString = "SELECT a FROM Estudiante a " +
                "WHERE :apellidoEstudiante=a.apellidoEst AND" +
                ":nombreEstudiante=a.nombreEst";

        Query query = em.createQuery(queryString);
        query.setParameter("apellidoEstudiante", apellido.toLowerCase());
        query.setParameter("nombreEstudiante", nombre.toLowerCase());

        return (Estudiante) query.getSingleResult();

    }

    /**
     * Verifica si ya existe el numero de documento de entrada en la base de datos
     * 
     * @param true si ya existe, false si no
     * @return referencia de tipo Estudiante
     */
    public boolean verificarDocumentoYaRegistrado(long documento) {

        String queryString ="SELECT u from Estudiante u WHERE u.docestudiante=" + String.valueOf(documento);
        
        try{
        Query query = em.createQuery(queryString);
        if(query.getSingleResult()==null)
            return false;
        else
            return true;
        }
        catch(NoResultException e){
            return false;
        }
    }

    /**
     * La funcion borra un estudiante por nombre y apellido, si no lo encuentra, no lo borra y retorna false
     * si lo encuentra y lo borra, devuelve true
     * @param apellido
     * @param nombre
     * @return true si lo borra, false si no
     */
    public boolean borrarEstudiantePorNombreYApellido(String apellido, String nombre) {
        Estudiante e = encontrarEstudiantePorNombreYApellido(apellido, nombre);//en este caso podemos borrar un usuario por nombre
        if (e != null) {
            em.remove(e);
            return true;
        }
        else {
            return false;
        }


    }

    /**
     * Cambia el parametro de estudiante inscrito a 1 (cambia de no inscrito a inscrito).
     * si no encuentra al estudiante con ese nombre y apellidos, se retorna null,
     *
     * @param apellido
     * @param nombre
     * @return la referencia del estudiante encontrado,null si no se encuentra el
     * estudiante
     */
    public Estudiante ActualizarEstudianteAInscrito(String apellido, String nombre) {
        em.getTransaction().begin();
        Estudiante e = this.encontrarEstudiantePorNombreYApellido(apellido, nombre);
        if (e != null) {
            e.setInscrito(1);
        }
        else {
            return null;
        }
        em.getTransaction().commit();
        return e;
    }

    /**
     * Cambia el parametro de estudiante inscrito a el escogido por el usuario.
     * si no encuentra al estudiante con ese documento, se retorna null,
     *
     * @param docestudiante
     * @return la referencia del estudiante encontrado,null si no se encuentra el
     * estudiante
     */
    public Estudiante ActualizarEstudianteAInscrito(Long docestudiante) {
        em.getTransaction().begin();
        Estudiante e = this.encontrarEstudiantePorDocumento(docestudiante);
        if (e != null) {
            e.setInscrito(1);
        }
        else {
            JOptionPane.showMessageDialog(null, "Error al actualizar estudiante a inscrito", null, JOptionPane.ERROR_MESSAGE);
        }
        em.getTransaction().commit();
        return e;
    }

    /**
     * Cambia el parametro de estudiante matriculado a 1 (cambia de no matriculado a matriculado).
     * si no encuentra al estudiante con ese nombre y apellidos, se retorna null,
     *
     * @param apellido
     * @param nombre
     * @return la referencia del estudiante encontrado,null si no se encuentra el
     * estudiante
     */
    public Estudiante ActualizarEstudianteAMatriculado(String apellido, String nombre) {//Equivale a formalizar matricula
        em.getTransaction().begin();
        Estudiante e = this.encontrarEstudiantePorNombreYApellido(apellido, nombre);
        if (e != null) {
            e.setMatriculado(1);
        }
        em.getTransaction().commit();
        return e;
    }

    /**
     * Devuelve la lista completa de estudiantes, ya sean preinscritos, inscritos o matriculados
     *
     * @return Collection<estudiante> con la lista de estudiantes
     */
    public Collection<Estudiante> EncontrarEstudiantes() { //encontrar todos los usuarios
        Query query = em.createQuery("SELECT u FROM Estudiante u");// Ojo la sentencia está en Java Query Language no SQL
        return (Collection<Estudiante>) query.getResultList(); // me guarda la lista de todos los usuarios en mi coleccion
    }

    /**
     * Devuelve la lista completa de estudiantes matriculados
     *
     * @return Collection<estudiante> con la lista de estudiantes matriculados
     */
    public List<Estudiante> EncontrarEstudiantesMatriculados() {
        Query query = em.createQuery("SELECT u FROM Estudiante u WHERE u.matriculado=1");
        return (List<Estudiante>) query.getResultList();
    }

    /**
     * Devuelve la lista completa de estudiantes inscritos
     *
     * @return Collection<estudiante> con la lista de estudiantes inscritos
     */
    public List<Estudiante> EncontrarEstudiantesInscritos() {
        Query query = em.createQuery("SELECT u FROM Estudiante u WHERE u.inscrito=1");
        return (List<Estudiante>) query.getResultList();
    }

    /**
     * Devuelve la lista completa de estudiantes inscritos
     *
     * @return Collection<estudiante> con la lista de estudiantes inscritos
     */
    public List EncontrarEstudiantesPreinscritos() {
        Query query = em.createQuery("SELECT u FROM Estudiante u");
        List result;
        result = query.getResultList();
        if (query.getResultList() != null) {
            return query.getResultList();
        }
        else {
            return null;
        }
    }

    /**
     * Esta fuincion retorna el ultimo Id del ultimo estudiante asignado
     * El id retornado es un entero tipo Long sin signo 
     * 
     * @return Long con el valor del ultimo Id, o null si ocurre algun error
     */
    public Long retornarultimoId() {
        Query query;
        try {
            query = em.createQuery("SELECT u.idestudiante from Estudiante u ORDER BY idestudiante DESC LIMIT 1");
            return (Long) query.getResultList().get(0);
        }
        catch (IndexOutOfBoundsException e) {
            return new Long(0);
        }

    }

    /**
     * Funcion utilitaria para encontrar la lista de los preinscritos
     * ordenados por fecha desde el mas antiguo (el primero que se inscribio
     * hasta el ultimo inscrito
     *
     * @return Estructura tipo Collection<Estudiante> con el listado
     * de preinscritos.
     */
    public List EncontrarEstudiantesPreinscritosPorFecha() {
        Query query = em.createQuery("SELECT u from Estudiante u ORDER BY idEstudiante DESC LIMIT 1");
        List result;
        result = query.getResultList();
        return (result);
    }

    public Estudiante encontrarEstudiantePorDocumento(long documento) {
        Query query = em.createQuery("SELECT u from Estudiante u WHERE u.docestudiante="+String.valueOf(documento));
        Object result = query.getSingleResult();
        return (Estudiante) (result);
    }

    public Estudiante ActualizarEstudianteAMatriculado(Long docestudiante) {
        em.getTransaction().begin();
        Estudiante e = this.encontrarEstudiantePorDocumento(docestudiante);
        if (e != null) {
            e.setMatriculado(1);
        }
        else {
            JOptionPane.showMessageDialog(null, "No se pudo encontrar al estudiante con documento"+docestudiante, null, JOptionPane.ERROR_MESSAGE);
        }
        em.getTransaction().commit();
        return e;
    }

    public boolean actualizarDatosPersonales(long docidentidadviejo,
                                             String docidentidadnuevo,
                                             String nombre,
                                             String apellido,
                                             int telefono,
                                             String fechanacimiento,
                                             String direccion)
    {
        em.getTransaction().begin();
        Estudiante e = this.encontrarEstudiantePorDocumento(docidentidadviejo);
        if (e != null) {
            e.setDocEstudiante(Long.valueOf(docidentidadnuevo));
            e.setNombreEst(nombre);
            e.setApellidoEst(apellido);
            e.setTelefonoEst(telefono);
            e.setFechaNacimientoEst(fechanacimiento);
            em.getTransaction().commit();
            return true;
        } 
            return false;
    }

    public boolean actualizarDatosDePadre(long docidentidadviejo,
                                          String nombrepadre,
                                          String apellidopadre,
                                          long documentopadre,
                                          int telefonopadre) {
        em.getTransaction().begin();
        Estudiante e = this.encontrarEstudiantePorDocumento(docidentidadviejo);
        if (e != null) {
            e.setNombrePadre(nombrepadre);
            e.setApellidoPadre(apellidopadre);
            e.setDocPadre(documentopadre);
            e.setTelPadre(telefonopadre);
            em.getTransaction().commit();
            return true;
        }
            return false;
    }

    public boolean actualizarDatosDeMadre(long docidentidadviejo,
                                          String nombremadre,
                                          String apellidomadre,
                                          long documentomadre,
                                          int telefonomadre) {
        em.getTransaction().begin();
        Estudiante e = this.encontrarEstudiantePorDocumento(docidentidadviejo);
        if (e != null) {
            e.setNombreMadre(nombremadre);
            e.setApellidoMadre(apellidomadre);
            e.setDocMadre(documentomadre);
            e.setTelMadre(telefonomadre);
            em.getTransaction().commit();
            return true;
        }
            return false;

    }
    public boolean cambiarEstudianteDeCurso(String idCurso, long docestudiante){

        em.getTransaction().begin();
        Estudiante e = this.encontrarEstudiantePorDocumento(docestudiante);
        if (e != null) {
            e.setIdCurso(idCurso);
            em.getTransaction().commit();
            return true;

        }
            return false;

    }
    public Collection<Estudiante> encontrarEstudiantesSinUsuario() {
        em.getTransaction().begin();
        Query query = em.createQuery("SELECT e FROM Estudiante e WHERE e.nombreUsuario IS NULL ORDER BY apellidoEst");
        Collection<Estudiante> e= query.getResultList();
        em.close();
        em.getTransaction().commit();
        return e;
    }
    public Collection<Estudiante> encontrarEstudiantesConUsuario() {
        em.getTransaction().begin();
        Query query = em.createQuery("SELECT e FROM Estudiante e WHERE e.nombreUsuario IS NOT NULL ORDER BY apellidoEst");
        Collection<Estudiante> e= query.getResultList();
        em.close();
        em.getTransaction().commit();
        return e;
    }
     public void asignarUsuarioAEstudiante(Long docEst, String nombreUsuario) {
        em.getTransaction().begin();
        Estudiante e = this.encontrarEstudiantePorDocumento(docEst);
        e.setNombreUsuario(nombreUsuario);
        em.getTransaction().commit();
    }
     //busca a los estudiantes preinscritos por el grado al que aspiran
     public List<Estudiante> encontrarEstudiantesPorGradoPreinscrito(String idgrado) {
        em.getTransaction().begin();
        Query query = em.createQuery("SELECT e FROM Estudiante e WHERE e.idgrado="+idgrado+" AND e.preinscrito=1");
        List<Estudiante> e= query.getResultList();
        em.getTransaction().commit();
        return e;
    }

    public List<Estudiante> encontrarEstudiantesPorGradoInscrito(String idgrado) {
        em.getTransaction().begin();
        Query query = em.createQuery("SELECT e FROM Estudiante e WHERE e.idgrado="+idgrado+" AND e.inscrito=1");
        List<Estudiante> e= query.getResultList();
        em.getTransaction().commit();
        return e;
    }
    public List<Estudiante> encontrarEstudiantesPorGradoMatriculado(String idgrado) {
        em.getTransaction().begin();
        Query query = em.createQuery("SELECT e FROM Estudiante e WHERE e.idgrado="+idgrado+" AND e.matriculado=1");
        List<Estudiante> e= query.getResultList();
        em.getTransaction().commit();
        return e;
    }

    public List<Estudiante> encontrarEstudiantesPorCursoMatriculado(String idcurso) {
        em.getTransaction().begin();
        Query query = em.createQuery("SELECT e FROM Estudiante e WHERE e.idcurso="+idcurso+" AND e.matriculado=1 ORDER BY e.apellidoest ASC");
        List<Estudiante> e= query.getResultList();
        em.getTransaction().commit();
        return e;
    }
}
